///////////////////////////////////////////////////////////////////////////////
//
// Licensed under the MIT License
//
// Copyright (c) 2010 Chris Colinsky
// All Rights Reserved
//
// version	0.5
// http://code.google.com/p/sugarcookie/
// http://code.google.com/p/sugarcookie/wiki/License
//
////////////////////////////////////////////////////////////////////////////////

package sugarcookie.file {
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	
	import mx.logging.*;
	import mx.utils.ObjectUtil;
	
	import sugarcookie.error.ApplicationError;
	import sugarcookie.events.GenericEvent;
	import sugarcookie.utils.StringUtil;
	
	/**
	 * Proxy for the Loader class.
	 */
	public class FileLoader extends MovieClip {
		private var _file:Loader;
		private var _info:LoaderInfo;
		private var _uri:String;
		private var _log:ILogger;
		
		public static const LOAD_INIT:String = "loadInit";
		public static const LOAD_COMPLETE:String = "loadComplete";
		public static const LOAD_PROGRESS:String = "loadProgress";
		
		public var id:String;
		
		public function FileLoader(uri:String=null) {
			_uri = uri;
			_log = Log.getLogger(StringUtil.getFormattedClassName(this));
		}
		
		public function get uri():String { return _uri; }
		public function set uri(uri:String):void { _uri = uri; }
		
		public function load():void {
			if (_uri==null) throw new ApplicationError("No source URI has been defined!");
			
			_file = new Loader();
			var context:LoaderContext = new LoaderContext();
			context.applicationDomain = ApplicationDomain.currentDomain;
			var request:URLRequest = new URLRequest(_uri);
			configureListeners(_file.contentLoaderInfo);
			
			try {
				_file.load(request, context);
			} catch (error:SecurityError) {
				_log.error("Unable to load file: "+ObjectUtil.toString(error));
			}
			addChild(_file);
		}
		
		private function configureListeners(dispatcher:IEventDispatcher):void {
			dispatcher.addEventListener(Event.COMPLETE, completeHandler,false,0,true);
			dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler,false,0,true);
			dispatcher.addEventListener(Event.INIT, initHandler,false,0,true);
			dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler,false,0,true);
			dispatcher.addEventListener(Event.OPEN, openHandler,false,0,true);
			dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler,false,0,true);
			dispatcher.addEventListener(Event.UNLOAD, unLoadHandler,false,0,true);
		}
		
		private function removeListeners(dispatcher:IEventDispatcher):void {
			dispatcher.removeEventListener(Event.COMPLETE, completeHandler);
			dispatcher.removeEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
			dispatcher.removeEventListener(Event.INIT, initHandler);
			dispatcher.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			dispatcher.removeEventListener(Event.OPEN, openHandler);
			dispatcher.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
			dispatcher.removeEventListener(Event.UNLOAD, unLoadHandler);
		}
        
        private function completeHandler(event:Event):void {
            _log.debug("completeHandler: " + event);
            _info = LoaderInfo(_file.contentLoaderInfo);
            dispatchEvent(new GenericEvent(FileLoader.LOAD_COMPLETE,true,false,true,false,{target:this}));
        }
        
        private function initHandler(event:Event):void {
            _log.debug("initHandler: " + event);
            dispatchEvent(new GenericEvent(FileLoader.LOAD_INIT,true,false,true,false,{target:this}));
        }

        private function httpStatusHandler(event:HTTPStatusEvent):void {
            _log.debug("httpStatusHandler: " + event);
        }

        private function ioErrorHandler(event:IOErrorEvent):void {
            _log.fatal("ioErrorHandler: " + event);
        }

        private function openHandler(event:Event):void {
            _log.debug("openHandler: " + event);
        }

        private function progressHandler(event:ProgressEvent):void {
            var p:Number = event.bytesLoaded/event.bytesTotal;
            dispatchEvent(new GenericEvent(FileLoader.LOAD_PROGRESS,false,false,false,false,{perc:p}));
        }

        private function unLoadHandler(event:Event):void {
            _log.debug("unLoadHandler: " + event);
            removeChild(_file);
			removeListeners(_file.contentLoaderInfo);
            _file = null;
        }
		
		public function get content():DisplayObject {
			return _file.content;
		}
        //Legacy API
        public function get file():Loader {
        	return Loader(removeChild(_file));
        }
        
        public function get info():LoaderInfo {
        	return _info;
        }
        
        public function unload():void {
        	if (_file!=null) _file.unload();
        	else _log.error("loader has already been reparented!");
        }
	}
}